
{% if not is_finite %}
/**
 {{ method_description }}
 */
public lazy var {{ name.lower_camel_case }}: Observable<{% if return_type %}{{ return_type.name }}{% else %}Void{% endif %}> = create{{ name.upper_camel_case }}Observable({% for param in params %}{{ param.name.lower_camel_case }}: {{ param.type_info.name }}{{ ", " if not loop.last }}{% endfor %})
{% endif %}

{% if is_finite %}
/**
 {{ method_description }}
 */
{% endif %}
{% if is_finite %}public func {{ name.lower_camel_case }}{% else %}private func create{{ name.upper_camel_case }}Observable{% endif %}({% for param in params %}{{ param.name.lower_camel_case }}: {{ param.type_info.name }}{{ ", " if not loop.last }}{% endfor %}) -> Observable<{% if return_type %}{{ return_type.name }}{% else %}Void{% endif %}> {
    return Observable.create { [unowned self] observer in
        {% if params|length > 0 %}var{% else %}let{% endif %} request = {{ package.upper_camel_case.replace('_', '').replace('.', '_') }}_Subscribe{{ name.upper_camel_case }}Request()

        {% for param in params %}
            {% if param.type_info.is_primitive %}
        request.{{ param.name.lower_camel_case }} = {{ param.name.lower_camel_case }}
            {% else %}
        request.{{ param.name.lower_camel_case }} = {{ param.name.lower_camel_case }}.rpc{{ param.name.upper_camel_case }}
            {% endif %}
        {% endfor %}

        let serverStreamingCall = self.service.subscribe{{ name.upper_camel_case }}(request, handler: { (response) in

            {% if return_type.is_repeated %}
	    let {{ name.lower_camel_case }} = response.{{ return_name.lower_camel_case }}.map{ {{ return_type.inner_name }}.translateFromRpc($0) }
            {% else %}
                 {% if return_type.is_primitive %}
            let {{ name.lower_camel_case }} = response.{{ return_name.lower_camel_case }}{% if return_name.lower_snake_case.endswith("type") %}_p{% endif %}
                {% else %}
            let {{ name.lower_camel_case }} = {{ return_type.name }}.translateFromRpc(response.{{ return_name.lower_camel_case }})
                {%- endif %}
            {% endif %}

            {% if has_result %}
            let result = {{ plugin_name.upper_camel_case }}Result.translateFromRpc(response.{{ plugin_name.lower_camel_case }}Result)

            switch (result.result) {
            case .success:
                observer.onCompleted()
            case .next:
                observer.onNext({{ name.lower_camel_case }})
            default:
                observer.onError({{ plugin_name.upper_camel_case }}Error(code: result.result, description: result.resultStr))
            }
            {% else %}
            observer.onNext({{ name.lower_camel_case }})
            {% endif %}
        })

        return Disposables.create {
            serverStreamingCall.cancel(promise: nil)
        }
    }
    .retry { error in
        error.map {
            guard $0 is Runtime{{ plugin_name.upper_camel_case }}Error else { throw $0 }
        }
    }
    .share(replay: 1)
}
